Rust设计模式探索:crate间接口相互调用 | 您所在的位置:网站首页 › rust 日志库 每个crate都需要依赖 › Rust设计模式探索:crate间接口相互调用 |
在程序设计中我们常常将一个复杂的程序,划分为若干个组件,这些组件最后通过一个容器组装并管理起来,然后程序通过这个容器对外暴露功能。 在最理想的情况下,这些组件应该是相互独立的,他们不相互调用,不会反过来去访问容器的其它部分,像砖块一样垒起一个程序。这样的设计当然很好,但也很难。在一个比较复杂的工程中多多少少会遇到需要模块间相互调用的需求。 实现这个需求,有几种做法: 方法1:组件内对容器弱引用组件中持有一个容器的引用(或弱引用),通过弱引用来访问容器的其它部分。 一般来说在rust中比较少采用这种设计,因为rust中缺乏对编写相互依赖结构的支持,写起来难受,还容易出bug。 struct ComponentA { container: Weak, // ... } struct Container { component_a: Arc, component_b: Arc, component_c: Arc, // ... } 方法2:参数注入容器的引用程序中所有函数都传递整个容器的引用作为参数,那么一个组件就可以通过这个引用访问其它组件提供的方法了。 但这种做法也有一些问题,这样要求组件和容器需要定义在同一个crate中,如果容器定义在比组件更上层的crate中,那么组件就没法拿到容器的类型,也没法定义一个需要容器引用的方法了。 struct Container { component_a: ComponentA, component_b: ComponentB, component_c: ComponentC, // ... } impl ComponentA { fn foo(container: &Container) { // 可以通过container去访问另一个组件提供的方法 container.component_b.bar( // 自身组件因为在同一个模块内,可以访问其字段 container.component_a.x ); } } 方法3:接口实现分离1当工程复杂起来之后,我们则一般倾向用crate而非mod去组织组件。crate的依赖结构就变成了 但使用crate带来的一个问题是crate与crate之间不能相互依赖,使得crate提供的接口在crate之间无法相互调用(但其实有在链接时的魔法linkme,使得crate之间能相互调用)。 为了解决这个问题,可以引入一个Middle层,将一个程序的所有状态以及组件提供的接口都放在Middle层;而接口的实现和注册则放在Component层: rustc就是这么做的,在middle中定义了GlobalCtxt |
CopyRight 2018-2019 实验室设备网 版权所有 |